import { getIfMatch, genKeyValueArraysFromQueryString, extractRequestParamsToObject, extractParamNames } from "./urlUtil"

// 需要mock的网络请求信息
const mockStepListMap = {}  // { planId1_suiteId1: [] }

// 需要监听请求参数的网络请求信息
const networkEqualEqualListMap = {}    // { planId1_suiteId1: [] }

const getKey = (planId, suiteId) => `${planId}_${suiteId}`

export const addMockStepToMap = ({ planId, suiteId, data, opts }) => {
  if (!mockStepListMap[getKey(planId, suiteId)]) {
    mockStepListMap[getKey(planId, suiteId)] = []
  }

  const { mock, ajax } = data
  const { data: mockData } = mock

  const { url: mockUrl, contentType } = ajax
  const ifMatch = getIfMatch(mockUrl, opts.env)

  mockStepListMap[getKey(planId, suiteId)].push({
    ifMatch: request => ifMatch(request.url()),
    response: {
      status: 200,
      contentType,    // 此处为ajax定义的
      body: mockData
    }
  })
}

export const addNetworkEuqlStepToMap = ({ planId, suiteId, data, resolve, opts }) => {
  const key = getKey(planId, suiteId)

  if (!networkEqualEqualListMap[key]) {
    networkEqualEqualListMap[key] = []
  }

  const { ajax, filterParamNames = '', compareParamNames = '' } = data
  const filterParamList = genKeyValueArraysFromQueryString(filterParamNames)

  const { url } = ajax
  const ifMatchUrl = getIfMatch(url, opts.env)
  const ifMatchParams = request => {
    let currentParamObject = extractRequestParamsToObject(request)
    return filterParamList.every(([key, value]) => currentParamObject[key] === value)
  }

  networkEqualEqualListMap[key].push({
    ifMatch: request => ifMatchUrl(request.url()) && ifMatchParams(request),
    compareParamNames: extractParamNames(compareParamNames),        // a&b => [a, b],   a=1&b=2  => [a,b]
    resolve
  })
}

export const listenPageRequest = async (page, planId, suiteId) => {
  await page.setRequestInterception(true)

  page.on('request', request => {
    // 针对图片，样式，字体文件，在不含任何截图相关断言的情况下，可以直接禁掉请求
    // if (['image', 'stylesheet', 'font'].includes(request.resourceType())) {
    //   return request.abort();
    // }

    const key = getKey(planId, suiteId)

    // network equal
    const networkEqualStepList = networkEqualEqualListMap[key] || []
    //只返回匹配到的第一个，所以如果一个网络请求在多次network相等的step中匹配，第一次的被匹配，后续的也无效
    const matchedNetworkEqualStepIndex = networkEqualStepList.findIndex(({ ifMatch }) => ifMatch(request))

    if (matchedNetworkEqualStepIndex >= 0) {
      let { compareParamNames, resolve } = networkEqualStepList[matchedNetworkEqualStepIndex]
      const requestParamObject = extractRequestParamsToObject(request)
      const compareParamObject = compareParamNames.reduce((result, key) => { result[key] = requestParamObject[key]; return result; }, {})

      networkEqualStepList.splice(matchedNetworkEqualStepIndex, 1)
      resolve(JSON.stringify(compareParamObject))
    }

    // mock
    const mockStepList = mockStepListMap[key] || []
    const matchedMockStep = mockStepList.find(({ ifMatch }) => ifMatch(request))     //只返回匹配到的第一个，所以如果mock多次，后续的也无效

    if (matchedMockStep) {
      request.respond(matchedMockStep.response)
    } else {
      // const headers = request.headers()
      // headers['auto-test-robot'] = '1'
      request.continue()
    }
  })

  page.on('close', () => {
    delete mockStepListMap[getKey(planId, suiteId)]
    delete networkEqualEqualListMap[getKey(planId, suiteId)]
  })
}
